/**
 * Urban Parks 
 *
 * Team M&M'S 
 * Michael Pogson
 * Michael Satran Jr.
 * Stephen Hunter
 * 
 * Date: ${date}
 */
package model;

import java.util.ArrayList;
import java.util.Collection;

	
	
/**
 * 
 * @author Michael Satran Jr, Michael Pogson, Stephen Hunter
 * @version Winter 2012
 */
public class Job {
	
	/**
	 * The list of volunteers signed up for the job.
	 */
	private final Collection<Volunteer> my_volunteers = new ArrayList<Volunteer>();
	
	/**
	 * The starting date for this job.
	 */
	private Date my_startDate;
	
	/**
	 * The date teh job ends.
	 */
	private Date my_endDate;
	
	/**
	 * The description of the work to be performed for this job.
	 */
	private String my_jobDescription;
	
	/**
	 * The difficulty level of the job expressed as an int.
	 */
	private int my_jobDifficulty;
	
	/**
	 * The name of the park that this job is for.
	 */
	private String my_parkName;
	
	/**
	 * Contains the descriptions for each difficulty level.
	 */
	public static String[] DIFFICULTY_LEVELS = 
		{ "1. Light work (No lifting)", "2. Medium work (Lifting)", "3. Hard work (Lifting, Walking)" };
	
	/*
	 * @pre the_completionDate != null
	 * @pre the_creationDate != null
	 * @pre the_jobDescription != null
	 * @pre 0 < the_jobDifficulty < 4
	 * 
	 * @post The fields will not be null and will have their respective
	 * 		 given values
	 */
	/**
	 * Constructor creates a job with the given parameters.
	 * 
	 * @param the_completionDate The date the job is to be completed on
	 * @param the_creationDate The date the job was created on
	 * @param the_jobDescription The description of the job
	 * @param the_jobDifficulty The difficulty level of the job
	 * @param the_parkName The name of the park this job is for
	 * @throws IllegalArgumentException if any of the preconditions aren't met
	 */
	public Job(final Date the_startDate, final Date the_endDate, 
				final String the_jobDescription, final int the_jobDifficulty)
				throws IllegalArgumentException {
		if (the_endDate == null) {
			throw new IllegalArgumentException("Ending date is null.");
		} else {
			my_endDate = the_endDate;
		}
		
		if (the_startDate == null) {
			throw new IllegalArgumentException("Starting date is null.");
		} else {
			my_startDate = the_startDate;
		}
		
		if (the_jobDescription == null) {
			throw new IllegalArgumentException("Job description is null.");
		} else {
			my_jobDescription = the_jobDescription;
		}
		
		if (the_jobDifficulty < 0 || the_jobDifficulty > 3) {
			throw new IllegalArgumentException("Job difficulty value is invalid.");
		} else {
			my_jobDifficulty = the_jobDifficulty;
		}
	}
	
	/*
	 * @pre the_endDate != null
	 * 
	 * @post my_endDate == the_endDate
	 */
	/**
	 * Sets the job's end date to the given date.
	 * 
	 * @param the_endDate The date to set as the end date for the job
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public void setEndDate(final Date the_endDate) throws IllegalArgumentException {
		if (the_endDate == null) {
			throw new IllegalArgumentException("Date is null.");
		} else {
			my_endDate = the_endDate;
		}
	}
	
	/*
	 * @post Returns the end date for the job
	 */
	/**
	 * Returns the date that the job ends.
	 * 
	 * @return The end date for the job
	 */
	public Date getEndDate() {
		return my_endDate;
	}
	
	/*
	 * @pre the_startDate != null
	 * 
	 * @post my_startDate == the_startDate
	 */
	/**
	 * Sets the job's starting date to the given date.
	 * 
	 * @param the_startDate The date to set as the starting date for the job
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public void setStartDate(final Date the_startDate) throws IllegalArgumentException {
		if (the_startDate == null) {
			throw new IllegalArgumentException("Date is null.");
		} else {
			my_startDate = the_startDate;
		}
	}
	
	/*
	 * @post Returns the starting date for the job
	 */
	/**
	 * Returns the date on which the job starts.
	 * 
	 * @return The starting date of the job
	 */
	public Date getStartDate() {
		return my_startDate;
	}
	
	/*
	 * @post Returns the length of the job (In days)
	 */
	/**
	 * Returns the length of the job in days.
	 * 
	 * @return The length in days of the job
	 */
	public int getJobLength() {
		return my_startDate.daysBetween(my_endDate);
	}
	
	/*
	 * @pre the_jobDescription != null
	 * 
	 * @post my_jobDescription == the_jobDescription
	 */
	/**
	 * Sets the description of the job to the given description.
	 * 
	 * @param the_jobDescription The job description to set for this job
	 * @throws IllegalArgumentEception if the parameter is null
	 */
	public void setJobDescription(final String the_jobDescription) 
			throws IllegalArgumentException {
		if (the_jobDescription == null) {
			throw new IllegalArgumentException("Job description is null.");
		} else {
			my_jobDescription = the_jobDescription;
		}
	}
	
	/*
	 * @post Returns the job's description
	 */
	/**
	 * Returns the description of the job.
	 * 
	 * @return The description of the job
	 */
	public String getJobDescription() {
		return my_jobDescription;
	}
	
	/*
	 * @pre 0 < the_jobDifficulty < 4
	 * 
	 * @post my_jobDifficulty == the_jobDifficulty
	 */
	/**
	 * Sets the job difficulty level as 1, 2 or 3.
	 * 
	 * @param the_jobDifficulty The job difficulty level to be set for this job
	 * 							expressed as an int
	 * @throws IllegalArgumentException if the parameter < 0 or > 3
	 */
	public void setJobDifficulty(final int the_jobDifficulty) 
			throws IllegalArgumentException {
		if (the_jobDifficulty < 1 || the_jobDifficulty > 3) {
			throw new IllegalArgumentException("Difficulty level is invalid.");
		} else {
			my_jobDifficulty = the_jobDifficulty;
		}
	}
	
	/*
	 * @post Returns the job's difficulty level
	 */
	/**
	 * Returns the difficulty level of the job.
	 * 
	 * @return The difficulty level of the job
	 */
	public int getJobDifficulty() {
		return my_jobDifficulty;
	}
	
	/*
	 * @pre the_volunteer != null
	 * 
	 * @post The job's list of volunteers will contain the_volunteer
	 */
	/**
	 * Adds the given volunteer to the job's list of volunteers.
	 * 
	 * @param the_volunteer The volunteer to be added to the job's list of volunteers
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public void addVolunteer(final Volunteer the_volunteer) throws IllegalArgumentException {
		if (the_volunteer == null) {
			throw new IllegalArgumentException("Volunteer is inavlid.");
		} else {
			my_volunteers.add(the_volunteer);
		}
	}
	
	/*
	 * @post Returns all the volunteers for this job as a Collection
	 */
	/**
	 * Returns a Collection of all the volunteers for the job.
	 * 
	 * @return A Collection of all the volunteers for the job
	 */
	public Collection<Volunteer> getVolunteers() {
		return my_volunteers;
	}
	
	/*
	 * @pre the_volunteer != null
	 * 
	 * @post This job's lost of volunteers will not contain the_volunteer
	 */
	/**
	 * Removes the volunteer from the job's list of volunteers.
	 * 
	 * @param the_volunteer The volunteer to be removed from this job's list of volunteers
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public void removeVolunteer(final Volunteer the_volunteer) throws IllegalArgumentException {
		if (the_volunteer == null) {
			throw new IllegalArgumentException("Volunteer is null.");
		} else {
			my_volunteers.remove(the_volunteer);
		}
	}
	
	/*
	 * @pre the_parkName != null
	 * 
	 * @post my_parkName == the_parkName
	 */
	/**
	 * Sets the name of the park to the given name.
	 * 
	 * @param the_parkName The name to set as this job's park name
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public void setParkName(final String the_parkName) throws IllegalArgumentException {
		if (the_parkName == null) {
			throw new IllegalArgumentException("Park name is invalid.");
		} else {
			my_parkName = the_parkName;
		}
	}
	
	/*
	 * @post Returns the name of the park that this job for
	 */
	/**
	 * Returns the name of the park.
	 * 
	 * @return The name of the park
	 */
	public String getParkName() {
		return my_parkName;
	}
	
	/*
	 * @post Returns the information for the difficulty level of the job
	*/
	/**
	 * Returns the information for a specific level of the job.
	 * 
	 * @return The information for a specific level of the job
	 */
	public String getDifficultyInfo() {
		return DIFFICULTY_LEVELS[my_jobDifficulty-1];
	}
	
	/*
	 * @pre o != null
	 * 
	 * @post returns true of this job and the parameter are equals, false otherwise
	 */
	/**
	 * Returns true if this job is equals to the parameter, false otherwise.
	 * 
	 * @param Object o The object to be tested for equivalence with this job
	 * @returns True if this job equals the parameter, false otherwise
	 * @throws IllegalArgumentException if the parameter is null
	 */
	public boolean equals(Object o) throws IllegalArgumentException {
		if (o == null) {
			throw new IllegalArgumentException("Job is null.");
		}
		
		boolean answer = false;
		
		if(o instanceof Job) {
			if((my_startDate.equals(((Job)o).my_startDate ) &&
					my_endDate.equals(((Job)o).my_endDate) &&
					my_jobDescription.equals(((Job)o).my_jobDescription))) {
				answer = true;
			}	
		}
		return answer;
	}
	
	/*
	 * @post Returns a String representation of this job's information
	 */
	/**
	 * Returns a String representation of the job.
	 * 
	 * @returns A String representation of this job's information.
	 * 			start date - end date - description - difficulty
	 */
	public String toString() {
		String result;
		result = my_parkName + " - " + my_startDate + " thru " + my_endDate + " - " + my_jobDescription + " - " + 
				DIFFICULTY_LEVELS[my_jobDifficulty-1];
		
		return result;
	}
	
	/*
	 * @post Returns a String representation of this job's information for display
	 * 		 on a calendar
	 */
	/**
	 * Returns a String representation of the job for the calendar.
	 * 
	 * @return A String represenation of this job's information for display on a calendar.
	 * 			end date, park, description; all separated by new lines
	 */
	public String toStringForCalendar() {
		String result;
		result = "End Date: " + my_endDate + "\n" + 
		         "Park: " + my_parkName + "\n" +
				 "Description: " + my_jobDescription;
		return result;
	}
}
